package com.sunyard.utils.sm2;


import com.sunyard.utils.wxpayutil.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;

import java.math.BigInteger;

@Slf4j
public class SecureUtil_SM2 {


    /**
     * SM2签名
     *
     * @param data     签名原串
     * @param encoding 编码
     * @param userId   签名序列号
     * @return
     */
    public static String sign(String data, String encoding, String userId, String privateKeyHex) {
        try {
            SM2 sm2 = new SM2();
            log.info("签名原串 => " + data);
            //密钥转换成BigInteger
            BigInteger privateKey = new BigInteger(privateKeyHex, 16);
            //计算签名
            SM2_Result sret = sm2.Sign(userId.getBytes(),
                    data.getBytes(encoding), privateKey, null);

            log.info("得到签名：");
            log.info("r: "
                    + Hex.toHexString(sm2.BigIntegerToByteArray(sret.r)));
            log.info("s: "
                    + Hex.toHexString(sm2.BigIntegerToByteArray(sret.s)));

            return Hex.toHexString(sm2.BigIntegerToByteArray(sret.r))
                    + Hex.toHexString(sm2.BigIntegerToByteArray(sret.s));

        } catch (Exception e) {
            WXPayUtil.getLogger().error("Sign Error", e);
            return null;
        }
    }

//    public static void main(String[] args) {
//        //data 为qrCode值
//        String data = "202105310000004206";
//        //编码为UTF-8
//        String encoding = "UTF-8";
//        //密钥学列为 qrCode值
//        String userId = "202105310000004206";
//        //加密私钥
//        String privateKeyHex = "82C266A60500A5F4910B825CF7C4C9C16EF1DC0C530734F7427C9074F155A03E";
//        String sign = sign(data, encoding, userId, privateKeyHex);
//        System.out.println(sign);
//
//        //637bebb647548cc65c113ee9b0ee09ab3a305661a4ed0bb5cb344add019215de5d13894b0fee383a42d74a28d0be7fb3fa523d8e169191b3aed74f88fe795ef2
//        //公钥X
//        String publicKeyXHex = "A895766F67812F78B9DEBD9257AC9C326867E7460D3CD876FAE1E27B00937326";
//        //公钥Y
//        String publicKeyYHex = "0E2E3B9E0159893787C27B89E35FFB6FC6397B40E8EE9CAA33131D2A2254ACBE";
//        boolean validate = validate(sign, data, encoding, userId, publicKeyXHex, publicKeyYHex);
//        System.out.println(validate);
//    }


    /**
     * 验签
     *
     * @param sign     hex签名串
     * @param origData 原始串
     * @param encoding 编码
     * @param certId   密钥序列
     * @return
     */
    public static boolean validate(String sign, String origData, String encoding, String certId,
                                   String publicKeyXHex, String publicKeyYHex) {

        try {

            log.info("验签sign:" + sign);
            log.info("验签origData:" + origData);
            log.info("验签certId:" + certId);
            SM2 sm2 = new SM2();


            log.info("公钥X坐标PublicKeyXHex: " + publicKeyXHex);
            log.info("公钥Y坐标PublicKeyYHex: " + publicKeyYHex);

            ECPoint PA = sm2.GetPoint(new BigInteger(publicKeyXHex, 16), new BigInteger(publicKeyYHex, 16));

            String signRHex = sign.substring(0, sign.length() / 2);
            String signSHex = sign.substring(sign.length() / 2);

            //验证签名
            Boolean result = sm2.Verify(origData.getBytes(encoding),
                    certId.getBytes(encoding), PA, new BigInteger(signRHex, 16),
                    new BigInteger(signSHex, 16));

            return result;
        } catch (Exception e) {
            WXPayUtil.getLogger().error(e.getMessage(), e);
        }
        return false;
    }
}
